<?php

declare(strict_types=1);

namespace think\auth\service;

use think\App;
use think\auth\model\UserModel;
use think\db\exception\DbException;
use think\db\exception\DataNotFoundException;
use think\db\exception\ModelNotFoundException;
use think\exception\HttpException;

class User
{
    private App $app;

    public function __construct(App $app)
    {
        $this->app = $app;
    }

    /**
     * 创建一个用户
     * @param string $userName
     * @param string $password
     * @return UserModel
     * @throws DbException
     * @throws DataNotFoundException
     * @throws ModelNotFoundException
     */
    public function Create(string $userName, string $password): UserModel
    {
        $user = UserModel::FindByName($userName);
        if (!empty($user) && !$user->isEmpty()) throw new HttpException(500,'账号已存在');
        return UserModel::create(['username' => $userName, 'password' => password_hash($password, PASSWORD_DEFAULT)]);
    }

    /**
     * 从Request中或根据UID取得用户信息
     * @param int|string|null $uid
     * @return UserModel|null
     * @throws DbException
     * @throws DataNotFoundException
     * @throws ModelNotFoundException
     */
    public function Fetch(int|string $uid = null): ?UserModel
    {
        if (empty($uid)) {
            $token = $this->app->get('auth.token')->Fetch();
            if (!$token) return null;
            $uid = $token->claims()->get('jti');
        }
        return UserModel::FindById($uid);
    }

    /**
     * 根据ID获取用户.
     * @param int|string $uid
     * @return UserModel|null
     * @throws DbException
     * @throws DataNotFoundException
     * @throws ModelNotFoundException
     */
    public static function FindById(int|string $uid): UserModel|null
    {
        return UserModel::FindById($uid);
    }

    /**
     * 根据别名查找用户
     * @param string $alias
     * @return UserModel|null
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public static function FindByAlias(string $alias): UserModel|null
    {
        return UserModel::FindByAlias($alias);
    }

    /**
     * 获取用户.
     * @param string $name
     * @return UserModel|null
     * @throws DbException
     * @throws DataNotFoundException
     * @throws ModelNotFoundException
     */
    public static function FindByName(string $name): UserModel|null
    {
        return UserModel::FindByName($name);
    }
}
